package com.pug.ksd.filter;

import com.pug.ksd.constant.GatewayConstant;
import com.pug.result.ResultEnum;
import com.pug.result.ex.KsdValidationException;
import com.pug.utils.fn.asserts.Vsserts;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.net.URI;

import static com.pug.constant.PugContants.PUG_XQ_LOGIN_USER_TOKEN;

/**
 * Author: lqm
 * create: 2022/5/4 21:36
 * Lover: lqx
 *
 * @see
 */
@Component
public class GlobalLoginOrRegisterFilter implements GlobalFilter, Ordered, GatewayConstant {

//    @Resource
//    PugRedisOperator redisOperator;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    /**
     *  Mono 这个对象是WebFlux里面的
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        Flux<DataBuffer> body = request.getBody();
        URI uri = request.getURI();
        String path = uri.getPath();
        if(uri.getPath().contains(GatewayConstant.LOGIN_MESS_PATH)){
            //首先判断是否是短信登录
            return chain.filter(exchange);  //这个地方还没有处理
        }
        if(uri.getPath().contains(GatewayConstant.LOGIN_PWD_PATH)){
            //判断是否是密码登录
            return chain.filter(exchange);  //这个地方还没有处理
        }
        if(uri.getPath().contains(GatewayConstant.LOGOUT_PATH)){
            return chain.filter(exchange);
        }
        //如果不是登录就判断是否含有token
        String authUserId = request.getHeaders().getFirst("AuthUserId");
        String authToken = request.getHeaders().getFirst("AuthToken");
        if (Vsserts.isNotEmpty(authUserId) && Vsserts.isNotEmpty(authToken)) {
            // 根据用户id查询缓存中的token
//            String redisToken = redisOperator.get(PUG_XQ_LOGIN_USER_TOKEN  + authUserId);
            String redisToken=stringRedisTemplate.opsForValue().get(PUG_XQ_LOGIN_USER_TOKEN  + authUserId);
            // 如果是空，则去登录
            if (Vsserts.isEmpty(redisToken)) {
                //直接在前台响应地方跳转到登录去
                throw new KsdValidationException(ResultEnum.LOGIN_FAIL);
            }
            // 如果不是空，说明用户前台app或者小程序传递了token，
            // 把传递进来的token和缓存中的token进行比较看是否一致
            // google浏览器：说明它肯定退出一次然后又登录了 user:1 token 545454545
            // firefox浏览器：说明它肯定退出一次然后又登录了 user:1 token 878787878
            if (!redisToken.equalsIgnoreCase(authToken)) {
                throw new KsdValidationException(ResultEnum.SAME_LOGIN);
            }
            return chain.filter(exchange);
        }
        //如果用户id未空，或者token为空，则需要去登录（首先是不去登录的，首先去统一认证中心拿）
//        response.setStatusCode(HttpStatus.SEE_OTHER);
//        response.getHeaders().set("Location","http://localhost:7001/test");
//        return exchange.getResponse().setComplete();
        //最后全部不符合，就直接拒绝访问
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
